﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" xmlns:mshelp="http://msdn.microsoft.com/mshelp" xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5" 
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:tool="http://www.microsoft.com/tooltip"
XMLNS:[default]="http://ddue.schemas.microsoft.com/authoring/2003/5">
<head>
    <title>WCF Messaging Sample Using Channel</title>
    <meta content="text/html; CHARSET=utf-8" http-equiv="Content-Type" />
    <meta name="saave" content="history" />
    <link rel="stylesheet" type="text/css" href="../../../../CommonFiles/Classic.css" />
</head>
<body>
<table cellspacing="0" cellpadding="0" width="99%">
<tbody>
<tr>
<td>
    <div id="header">
        <table id="topTable" width="100%">
            <tbody>
                <tr id="headerTableRow1">
                    <td align="left">
                        <span id="runningHeaderText"></span>
                    </td>
                </tr>
                <tr id="headerTableRow2">
                    <td align="left">
                        <span id="nsrTitle">WCF Messaging Sample Using Channels</span>
                    </td>
                </tr>
                <tr id="headerTableRow2">
                    <td align="left"></td>
                </tr>
            </tbody>
        </table>
    </div>
    <div id="mainSection">
        <div id="mainBody">
            <p>This sample demonstrates how to use the Windows Azure Service Bus using WCF channels. </p>
            <p>The sample shows the use of WCF channels to send and receive messages via a Service Bus queue. The sample shows both session and non-session communication over the Service Bus. The sample prompts for service namespace credentials for the purpose of creating and deleting the queues, and sending and receiving messages. The credentials are used to authenticate with the Access Control 
                service, and acquire an access token that proves to the Service Bus infrastructure that the client is authorized to access the queue. The senders first send messages to the non-session queue which are then received by the receivers as they become available, illustrating a non-session communication using the WCF channel model. The senders then send messages to the session queue which are received by the session receivers, illustrating session-based communication using the WCF channel model.</p>
            <h2 class="heading">Prerequisites</h2>
            <div id="sectionSection0" class="section">
                <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
                    <p>If you haven't already done so, please read the release notes document that explains how to sign up for a Windows Azure account and how to configure your environment. </p>
                </content>
            </div>
            <h2 class="heading">Configuration File</h2>
            <div id="sectionSection2" class="section">
                <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
                    <p>The sender and receiver use NetMessagingBinding for non-session communication and CustomBinding for session communication. Both the bindings are defined in the respective App.Config files. 
                        NetMessagingBinding uses BinaryMessageEncoding as its encoder and NetMessagingTransportBindingElement as its transport element. 
                        TransportSettings is a part of the transport element, and represents the runtime factory used by the Service Bus. An extension section must be added to the configuration file in order to use Service Bus components with WCF.</p>
                    <p>In addition to the binding, both the config files have a <behaviors> section which defines TransportClientEndpointBehavior. Service Bus credentials are passed on to the client and service as this endpoint behavior. </p>
                    <div class="code" xmlns="">
                        <span codeLanguage="CSharp">
                            <table cellspacing="0" cellpadding="0" width="100%">
                                <tbody>
                                    <tr>
                                        <th>App.Config - Config Extensions and Binding</th>
                                    </tr>
                                    <tr>
                                        <td colspan="2">
                                            <pre>
                                              &lt;extensions&gt;
                                                &lt;bindingElementExtensions&gt;
                                                  &lt;add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, 
                                                               Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&gt;
                                                &lt;/bindingElementExtensions&gt;
                                                &lt;bindingExtensions&gt;
                                                  &lt;add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, 
                                                               Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&gt;
                                                &lt;/bindingExtensions&gt;
                                              &lt;/extensions&gt;
                                              &lt;bindings&gt;
                                                &lt;customBinding&gt;
                                                  &lt;binding name="customBinding" sendTimeout="00:02:00" receiveTimeout="00:00:30" openTimeout="00:02:00" closeTimeout="00:02:00"&gt;
                                                    &lt;binaryMessageEncoding /&gt;
                                                    &lt;netMessagingTransport manualAddressing="false" &gt;
                                                      &lt;transportSettings /&gt;
                                                    &lt;/netMessagingTransport&gt;
                                                  &lt;/binding&gt;
                                                &lt;/customBinding&gt;
                                                &lt;netMessagingBinding&gt;
                                                  &lt;binding name="messagingBinding" sendTimeout="00:02:00" receiveTimeout="00:00:30" openTimeout="00:02:00" closeTimeout="00:02:00" &gt;
                                                    &lt;transportSettings /&gt;
                                                  &lt;/binding&gt;
                                                &lt;/netMessagingBinding&gt;
                                              &lt;/bindings&gt;</pre>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </span>
                    </div>
                </content>
            </div>
            <h2 class="heading">Credentials</h2>
            <div id="sectionSection4" class="section">
                <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
                    <p>The sample gets user credentials and creates a NamespaceManager. This entity holds the credentials and is used for all messaging management operations - in this case, to create and delete queues.</p>
                    <div class="code" xmlns="">
                        <span codeLanguage="CSharp">
                            <table cellspacing="0" cellpadding="0" width="100%">
                                <tbody>
                                    <tr>
                                        <th>C#</th>
                                    </tr>
                                    <tr>
                                        <td colspan="2">
                                            <pre>
                                                public static void GetUserCredentials()
                                                {
                                                    // User namespace
                                                    Console.WriteLine("Please provide the namespace to use:");
                                                    serviceBusNamespace = Console.ReadLine();

                                                    // Issuer name
                                                    Console.WriteLine("Please provide the Issuer name to use:");
                                                    serviceBusIssuerName = Console.ReadLine();

                                                    // Issuer key
                                                    Console.WriteLine("Please provide the Issuer key to use:");
                                                    serviceBusIssuerKey = Console.ReadLine();
                                                }

                                                // Create the NamespaceManager for management operations (queue)
                                                static void CreateNamespaceManager()
                                                {
                                                    // Create SharedSecretCredential object for access control service
                                                    TokenProvider credentials = TokenProvider.CreateSharedSecretTokenProvider(serviceBusIssuerName, serviceBusIssuerKey);
                                                    
                                                    // Create the management Uri
                                                    Uri managementUri = ServiceBusEnvironment.CreateServiceUri("sb", serviceBusNamespace, string.Empty);
                                                    namespaceClient = new NamespaceManager(managementUri, credentials);
                                                }

                                                // Create the entity (queue)
                                                static Queue CreateQueue(bool session)
                                                {
                                                    string queueName = (session ? sessionQueueName : sessionlessQueueName);
                                                    QueueDescription queueDescription = new QueueDescription(queueName) { RequiresSession = session };

                                                    // Try deleting the queue before creation. Ignore exception if queue does not exist.
                                                    try
                                                    {
                                                        namespaceClient.DeleteQueue(queueDescription.Path);
                                                    }
                                                    catch (MessagingEntityNotFoundException)
                                                    {
                                                    }

                                                    return namespaceClient.CreateQueue(queueDescription);
                                                }                                                 
                                            </pre>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </span>
                    </div>
                    <p>The preceding code prompts for the issuer credential and then constructs the listening URI using that information. The static ServiceBusEnvironment.CreateServiceUri function is provided to help construct the URI with the correct format and domain name. It is strongly recommended that you use this function instead of building the URI from scratch because the URI construction logic and format might change in future releases. At present, the resulting URI is scheme://&lt;service-namespace&gt;.servicebus.windows.net/. </p>
                    <p>The CreateNamespaceManager() function creates the object to perform management operations, in this case creating and deleting queues. Both ‘https’ and ‘sb’ Uri schemes are allowed as a part of the service Uri.</p>
                    <p>The CreateQueue(bool session) function creates a queue with the RequireSession property set according to the argument passed.</p>
                </content>
            </div>
            <h2 class="heading">Sender</h2>
            <div id="sectionSection6" class="section">
                <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
                    <p>The Service Bus only supports IOutputChannel for sending messages using NetMessagingBinding or CustomBinding. Both the session-based and non-session send operations are mapped to the IOutputChannel.</p>
                    <div class="code" xmlns="">
                        <span codeLanguage="CSharp">
                            <table cellspacing="0" cellpadding="0" width="100%">
                                <tbody>
                                    <tr>
                                        <th>C#</th>
                                    </tr>
                                    <tr>
                                        <td colspan="2">
                                            <pre>
                                                // Get credentials as Endpoint behavior
                                                TransportClientEndpointBehavior securityBehavior = new TransportClientEndpointBehavior();
                                                securityBehavior.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(serviceBusIssuerName, serviceBusIssuerKey);

                                                // Create factory and channel using NetMessagingBinding
                                                NetMessagingBinding messagingBinding = new NetMessagingBinding("messagingBinding");
                                                EndpointAddress address = SampleManager.GetEndpointAddress(SampleManager.SessionlessQueueName, serviceBusNamespace);
                                                IChannelFactory&lt;IOutputChannel&gt; messagingChannelFactory = messagingBinding.BuildChannelFactory&lt;IOutputChannel&gt;(securityBehavior);
                                                messagingChannelFactory.Open();
                                                IOutputChannel messagingOutputChannel = messagingChannelFactory.CreateChannel(address);
                                                messagingOutputChannel.Open();

                                                // Create factory and channel using custom binding
                                                CustomBinding customBinding = new CustomBinding("customBinding");
                                                address = SampleManager.GetEndpointAddress(SampleManager.SessionQueueName, serviceBusNamespace);
                                                IChannelFactory&lt;IOutputChannel&gt; customChannelFactory = customBinding.BuildChannelFactory&lt;IOutputChannel&gt;(securityBehavior);
                                                customChannelFactory.Open();
                                                IOutputChannel customOutputChannel = customChannelFactory.CreateChannel(address);
                                                customOutputChannel.Open();
 
                                                public static EndpointAddress GetEndpointAddress(string queueName, string serviceBusNamespace)
                                                {
                                                    return new EndpointAddress(ServiceBusEnvironment.CreateServiceUri("sb", serviceBusNamespace, queueName));
                                                }</pre>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </span>
                    </div>
                    <p>Service Bus credentials are passed to the client via an endpoint behavior of 
                        type TransportClientEndpointBehavior.</p>
                    <p>The Endpoint address is constructed using the ServiceBusEnvironment.CreateServiceUri function and is of 
                        the form sb://&lt;service-namespace&gt;.servicebus.windows.net/&lt;entity-name&gt;. Note that the Uri scheme ‘sb’ is mandatory for all runtime operations such as send/receive.</p>
                    <p>To accomplish session communication over NetMessagingBinding, the BrokeredMessageProperty.SessionId must be set to the desired session value. All the messages with the same SessionId are grouped together in a single session. This property is required to be set for session-based communication and is optional for non-session communication.</p>
                    <div class="code" xmlns="">
                        <span codeLanguage="CSharp">
                            <table cellspacing="0" cellpadding="0" width="100%">
                                <tbody>
                                    <tr>
                                        <th>C#</th>
                                    </tr>
                                    <tr>
                                        <td colspan="2">
                                            <pre>
                                                string sessionName = rand.Next(SampleManager.NumSessions).ToString();

                                                // Creating BrokeredMessageProperty
                                                BrokeredMessageProperty property = new BrokeredMessageProperty();
                                                property.SessionId = sessionName;
                                                property.Label = "Order_" + Guid.NewGuid().ToString().Substring(0, 5);

                                                // Creating message and adding BrokeredMessageProperty to the properties bag
                                                Message message = Message.CreateMessage(binding.MessageVersion, "Order");
                                                message.Properties.Add(BrokeredMessageProperty.Name, property);

                                                // Sending message
                                                clientChannel.Send(message);</pre>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </span>
                    </div>
                </content>
            </div>
            <h2 class="heading">Receiver</h2>
            <div id="sectionSection6" class="section">
                <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
                    <p>The sample illustrates non-session receive over a Service Bus queue with the receive mode set to ‘Receive and Delete’. In this mode, the message is removed from the queue as soon as it is delivered to the receiver. This mode is useful when the communication between sender and receiver can tolerate loss of data. </p>
                    <p>The non-session receive operation is done using IInputChannel. Non-session receive operations require a single channel for communication with the queue. Since the receiver is in receive and delete mode, 
                        ReceiveContext.Complete operation is not required. In the sample, the while loop continuously polls the queue for message. If a message is available, the operation returns the message. If no more messages are available in the queue, the receive operation waits for the specified Timeout period for new messages to arrive. If no new messages are still available, it generates a TimeoutException.</p>
                    <p>In the sample, the service collects all the items in a single session and then displays the total at the end. The service is defined in its App.config file.</p>
                    <div class="code" xmlns="">
                        <span codeLanguage="CSharp">
                            <table cellspacing="0" cellpadding="0" width="100%">
                                <tbody>
                                    <tr>
                                        <th>C#</th>
                                    </tr>
                                    <tr>
                                        <td colspan="2">
                                            <pre>
                                                // Create channel listener and channel using NetMessagingBinding
                                                NetMessagingBinding messagingBinding = new NetMessagingBinding("messagingBinding");
                                                EndpointAddress address = SampleManager.GetEndpointAddress(SampleManager.SessionlessQueueName, serviceBusNamespace);
                                                TransportClientEndpointBehavior securityBehavior = new TransportClientEndpointBehavior();
                                                securityBehavior.TokenProvider = SampleManager.GetSharedSecretToken(serviceBusIssuerName, serviceBusIssuerKey);

                                                IChannelListener&lt;IInputChannel&gt; inputChannelListener = messagingBinding.BuildChannelListener&lt;IInputChannel&gt;(address.Uri, securityBehavior);
                                                inputChannelListener.Open();
                                                IInputChannel inputChannel = inputChannelListener.AcceptChannel();
                                                inputChannel.Open();

                                                while (true)
                                                {
                                                    try
                                                    {
                                                        // Receive message from queue. If no more messages available, the operation throws a TimeoutException.
                                                        Message receivedMessage = inputChannel.Receive(receiveMessageTimeout);
                                                        SampleManager.OutputMessageInfo("Receive", receivedMessage);
                                                    }
                                                    catch (TimeoutException)
                                                    {
                                                        break;
                                                    }
                                                }

                                                // Close
                                                inputChannel.Close();
                                                inputChannelListener.Close();</pre>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </span>
                    </div>
                    <p>The sample also illustrates session-based receive over the Service Bus queue with receive mode as ‘Peek Lock’. In this mode, the message is removed from the queue only after an explicit ReceiveContext.Complete() operation is performed by the receiver. If the ReceiveContext.Complete() is not received within the LockDuration, the message is unlocked and placed in the queue again. The LockDuration is a customizable property of the queue and can only be set during queue creation. </p>
                    <p>The session-based receive operation is performed using IInputSessionChannel. Session-based receive operations require a new session channel for every available session in the queue. An explicit ReceiveContext.Complete() operation is performed for every message received. In the sample, the while loop continuously polls the queue for available new sessions. If the session is available, AcceptChannel() creates a session channel for that particular session. The inner while loop receives all the messages in 
                        the sessions until the TryReceive operation returns false indicating no messages available for 
                        that session. This is repeated for all available sessions in the queue. If no new session is available in the queue, the AcceptChannel() request generates a TimeoutException.</p>
                    <div class="code" xmlns="">
                        <span codeLanguage="CSharp">
                            <table cellspacing="0" cellpadding="0" width="100%">
                                <tbody>
                                    <tr>
                                        <th>C#</th>
                                    </tr>
                                    <tr>
                                        <td colspan="2">
                                            <pre>
                                                // Create listener and channel using custom binding
                                                CustomBinding customBinding = new CustomBinding("customBinding");
                                                EndpointAddress address = SampleManager.GetEndpointAddress(SampleManager.SessionQueueName, serviceBusNamespace);
                                                TransportClientEndpointBehavior securityBehavior = new TransportClientEndpointBehavior();
                                                securityBehavior.TokenProvider = SampleManager.GetSharedSecretToken(serviceBusIssuerName, serviceBusIssuerKey);
                                                customBinding.GetProperty&lt;IReceiveContextSettings&gt;(new BindingParameterCollection()).Enabled = true;

                                                IChannelListener&lt;IInputSessionChannel&gt; inputSessionChannelListener = customBinding.BuildChannelListener&lt;IInputSessionChannel&gt;(address.Uri, securityBehavior);
                                                inputSessionChannelListener.Open();

                                                while (true)
                                                {
                                                    IInputSessionChannel inputSessionChannel = null;
                                                    try
                                                    {
                                                        // Create a new session channel for every new session available. If no more sessions available, 
                                                        // then the operation throws a TimeoutException.
                                                        inputSessionChannel = inputSessionChannelListener.AcceptChannel(acceptSessionReceiverTimeout);
                                                        inputSessionChannel.Open();

                                                        // TryReceive operation returns true if message is available otherwise it returns false.
                                                        Message receivedMessage;
                                                        while (inputSessionChannel.TryReceive(receiveSessionMessageTimeout, out receivedMessage))
                                                        {
                                                            if (receivedMessage != null)
                                                            {
                                                                SampleManager.OutputMessageInfo("Receive", receivedMessage);

                                                                // Since the binding has ReceiveContext enabled, a manual complete operation is mandatory 
                                                                // if the message was processed successfully.
                                                                ReceiveContext rc;
                                                                if (ReceiveContext.TryGet(receivedMessage, out rc))
                                                                {
                                                                    rc.Complete(TimeSpan.FromSeconds(10.0d));
                                                                }
                                                                else
                                                                {
                                                                    throw new InvalidOperationException("Receiver is in peek lock mode but receive context is not available!");
                                                                }
                                                            }
                                                            else
                                                            {
                                                                // This IInputSessionChannel doesn't have any more messages
                                                                break;
                                                            }
                                                        }

                                                        // Close session channel
                                                        inputSessionChannel.Close();
                                                        inputSessionChannel = null;
                                                    }
                                                    catch (TimeoutException)
                                                    {
                                                        break;
                                                    }
                                                    finally
                                                    {
                                                        if (inputSessionChannel != null)
                                                        {
                                                            inputSessionChannel.Abort();
                                                        }
                                                    }
                                                }

                                                // Close channel listener
                                                inputSessionChannelListener.Close();</pre>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </span>
                    </div>
                </content>
            </div>
            <h2 class="heading">Running the Sample</h2>
            <div id="Div2" class="section">
                <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
                    <p>To run the sample, build the solution in Visual Studio or from the command line, then run the executable ‘SampleManager.exe’. The program prompts for your service namespace and the issuer credentials. For the issuer secret, be sure to use the "Default Issuer Key" value (typically "owner") from the portal, rather than one of the management keys. </p>
                    <p><b>Expected Output - Sample Manager</b></p>
                    <div class="code" xmlns="">
                        <table cellspacing="0" cellpadding="0" width="100%">
                            <tbody>
                                <tr>
                                    <td colspan="2">
                                        <pre class="style2">
                                             Please provide the namespace to use: &lt;Service Namespace&gt;
                                             Please provide the Issuer name to use: &lt;Issuer Name&gt;
                                             Please provide the Issuer key to use: &lt;Issuer Key&gt;
                                             Creating Queues...
                                             Created OrderQueue_NoSession, Queue.RequiresSession = false
                                             Created OrderQueue_Session, Queue.RequiresSession = true                                         

                                             Launching senders and receivers...                                         

                                             Press [Enter] to exit.</pre>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    <p><b>Expected Output – Sender</b></p>
                    <div class="code" xmlns="">
                        <table cellspacing="0" cellpadding="0" width="100%">
                            <tbody>
                                <tr>
                                    <td colspan="2">
                                        <pre class="style2">
                                            Preparing to send messages to OrderQueue_NoSession...
                                             Started sending messages...
                                             Send: Order_9bc3d - Group 0.
                                             Send: Order_4ca9e - Group 1.
                                             Send: Order_4ed05 - Group 0.
                                             Send: Order_0618d - Group 2.
                                             Send: Order_f6429 - Group 3.
                                             Send: Order_2c0ba - Group 0.
                                             Send: Order_a928b - Group 2.
                                             Send: Order_707f7 - Group 3.
                                             Send: Order_e092a - Group 1.
                                             Send: Order_b068e - Group 1.
                                             Send: Order_d6b7f - Group 0.
                                             Send: Order_98b1b - Group 2.
                                             Finished sending messages

                                             Preparing to send messages to OrderQueue_Session...
                                             Started sending messages...
                                             Send: Order_05125 - Group 0.
                                             Send: Order_15aad - Group 1.
                                             Send: Order_19a20 - Group 3.
                                             Send: Order_df3d6 - Group 2.
                                             Send: Order_77f8d - Group 1.
                                             Send: Order_a857a - Group 0.
                                             Send: Order_43594 - Group 2.
                                             Send: Order_d3ece - Group 3.
                                             Send: Order_1f312 - Group 1.
                                             Finished sending messages                                         

                                             Sender complete. Press [Enter] to exit.  </pre>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    <p><b>Expected Output – Message Receiver</b></p>
                    <div class="code" xmlns="">
                        <table cellspacing="0" cellpadding="0" width="100%">
                            <tbody>
                                <tr>
                                    <td colspan="2">
                                        <pre class="style2">
                                            Ready to receive messages from OrderQueue_NoSession...
                                            Reading messages from queue OrderQueue_NoSession...
                                            Receiver Type: Receive and Delete
                                            Receive: Order_f87fb - Group 0.
                                            Receive: Order_cf32b - Group 1.
                                            Receive: Order_29195 - Group 0.
                                            Receive: Order_80c3d - Group 2.
                                            Receive: Order_e9758 - Group 3.
                                            Receive: Order_7578a - Group 0.
                                            Receive: Order_36de1 - Group 2.
                                            Receive: Order_478f8 - Group 3.
                                            Receive: Order_128b5 - Group 1.
                                            Receive: Order_64a86 - Group 1.
                                            Receive: Order_d7943 - Group 0.
                                            Receive: Order_7fc59 - Group 2.                                            

                                        Receiver complete. Press [Enter] to exit.</pre>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    <p><b>Expected Output - Session Message Receiver</b></p>
                    <div class="code" xmlns="">
                        <table cellspacing="0" cellpadding="0" width="100%">
                            <tbody>
                                <tr>
                                    <td colspan="2">
                                        <pre class="style2">
                                             Ready to receive messages from OrderQueue_Session...
                                             Reading messages from queue OrderQueue_Session...
                                             Receiver Type: PeekLock
                                             Receive: Order_df3d6 - Group 0.
                                             Receive: Order_f78dd - Group 0.
                                             Receive: Order_807eb - Group 1.
                                             Receive: Order_808e2 - Group 1.
                                             Receive: Order_f37d3 - Group 1.
                                             Receive: Order_c970d - Group 3.
                                             Receive: Order_77f8d - Group 3.
                                             Receive: Order_ff8bd - Group 2.
                                             Receive: Order_1a0f4 - Group 2. 

                                             Receiver complete. Press [Enter] to exit.</pre>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>                                                            
                </content>
            </div>
        </div>
        <P xmlns="">
        <hr />
        Did you find this information useful?
            <a href="http://go.microsoft.com/fwlink/?LinkID=155664">
              Please send your suggestions and comments about the documentation.
            </a>
        </P>
    </div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
